#ifndef UI_UI_CONTROLLER_H
#define UI_UI_CONTROLLER_H

#include <memory>
#include <mutex>
#include <unordered_map>

#include <crow.h>
#include <crow/mustache.h>

#include "common/more/uuid.h"

#include "ui_session/ui_session.h"

namespace Api
{
class Client;
} // namespace Api

namespace Ui
{

class UiController final
{
public:
    explicit UiController(std::shared_ptr<Api::Client> datenaroGate);
    ~UiController();
    void run();

    std::shared_ptr<Api::Client> datenaroGate();

    const crow::mustache::template_t& loginPageTemplate() const;
    const crow::mustache::template_t& rootPageTemplate() const;
    const crow::mustache::template_t& userPageTemplate() const;
    const crow::mustache::template_t& usersPageTemplate() const;
    const crow::mustache::template_t& newUserPageTemplate() const;

    const crow::mustache::template_t& error404() const;

    UiSessionPtr addSession(const Uuids::Uuid& sessionUuid, unsigned userId);
    void delSession(const Uuids::Uuid& sessionUuid);
    UiSessionPtr session(const Uuids::Uuid& sessionUuid) const;

private:
    std::shared_ptr<Api::Client> m_datenaroGate;
    std::unique_ptr<crow::SimpleApp> m_crowApplication;

    crow::mustache::template_t m_loginPageTemplate { "" };
    crow::mustache::template_t m_rootPageTemplate { "" };
    crow::mustache::template_t m_userPageTemplate { "" };
    crow::mustache::template_t m_usersPageTemplate { "" };
    crow::mustache::template_t m_newUserPageTemplate { "" };

    crow::mustache::template_t m_error404 { "" };

    mutable std::mutex m_sessionsUserIdsLock;
    std::unordered_map<Uuids::Uuid, UiSessionPtr> m_sessions;
};

} // namespace Ui

#endif // UI_UI_CONTROLLER_H
